package yto.freemarker.java8.stream;

import org.junit.Test;
import yto.freemarker.java8.entity.Employee;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

/**
 * 操作stream
 * <p>
 * 创建stream
 * <p>
 * 中间操作
 * <p>
 * 终止操作
 *
 * @author dongxing
 * @create 2018-06-23 13:23
 **/
public class TestStreamApi02 {

    List<Employee> list = Arrays.asList(new Employee("Zhansgan", 10, 200.0),
            new Employee("lisi", 20, 300.0),
            new Employee("wangwu", 30, 400.0),
            new Employee("zhangliu", 40, 500.0),
            new Employee("zhangliu", 40, 500.0),
            new Employee("zhangliu", 40, 500.0)
    );

    //中间操作

    /**
     * 筛选与操作
     * filter --接收lambda 从流中排除某些元素
     * limit --截断流 使其元素不超过给定数量
     * skip（n）  ---跳过元素，返回扔掉前n个的元素的流。如果不足n，则返回个空的流   与limit互补
     * distinct --筛选  通过equals和hashcode的方法
     */
    //  内部迭代。Stream的自己执行的
    @Test
    public void test1() {
        //中间操作:不会执行任何操作
        list.stream()
                .filter((e) -> {
                    System.out.println("stream的中间操作");
                    return e.getAge() > 30;
                })
                //终止操作：一次性执行所有的操作,即“惰性求值”
                .forEach(System.out::println);
    }

    @Test
    public void test2() {
        //中间操作:不会执行任何操作
        list.stream()
                .filter((e) -> {
                    System.out.println("stream的短路");
                    return e.getSolary() > 10;
                })
                .limit(2)
                //终止操作：一次性执行所有的操作,即“惰性求值”
                .forEach(System.out::println);
    }

    @Test
    public void test3() {
        //中间操作:不会执行任何操作
        list.stream()
                .filter((e) -> {
                    System.out.println("stream的短路");
                    return e.getSolary() > 10;
                })
                .skip(2)
                //终止操作：一次性执行所有的操作,即“惰性求值”
                .forEach(System.out::println);
    }

    @Test
    public void test4() {
        //中间操作:不会执行任何操作
        list.stream()
                .filter((e) -> {
                    System.out.println("stream的短路");
                    return e.getSolary() > 10;
                })
                //去重
                .distinct()
                //终止操作：一次性执行所有的操作,即“惰性求值”
                .forEach(System.out::println);
    }


    /**
     * 映射
     * <p>
     * map --接收lambda 将元素转换成其他的形式或提取信息，接收一个函数作为参数，该函数会被应用到每个元素上，并将其映射成一个新的元素
     * flatmap --接收一个函数作为参数，将流中 的每个值都换成另一个流，然后把所有的流链接成一个流
     */

    @Test
    public void test5() {

        List<String> lists = Arrays.asList("aaa", "bbb", "vccc", "ddd");
        lists.stream()
                //使用的是function函数
                .map((e) -> e.toUpperCase())
                .forEach(System.out::println);

        System.out.println("---------------");

        list.stream()
                //使用的是function函数
                .map(Employee::getName)
                .distinct()
                .forEach(System.out::println);

        System.out.println("-----------------");

        lists.stream()
                .map(TestStreamApi02::getCharacter)
                .forEach((e) ->
                        e.forEach(System.out::println)
                );
        System.out.println("-----------------");

        lists.stream()
                .flatMap(TestStreamApi02::getCharacter)
                .forEach(System.out::println);


    }


    public static Stream<Character> getCharacter(String string) {
        List<Character> list1 = new ArrayList<>();
        for (Character c : string.toCharArray()) {
            list1.add(c);
        }
        return list1.stream();


    }


    /**
     * 排序
     * <p>
     * sorted()   自然排序  --comparable
     * sorted(comparator com)   定制排序--comparator
     */
    @Test
    public void test6() {

        List<String> lists = Arrays.asList("aaa", "bbb", "vccc", "ddd");
        lists.stream()
                .sorted()
                .forEach(System.out::println);

        System.out.println("---------------");

        list.stream()
                .sorted((e1, e2) -> {
                    if (e1.getAge().equals(e2.getAge())) {
                        return e1.getName().compareTo(e2.getName());
                    } else {
                        return e1.getAge().compareTo(e2.getAge());
                    }
                })
                .forEach(System.out::println);


    }

}
